一、Comparable 和 Comparator 架構圖
java.util.Collection  (介面)
│
├── java.util.List  (介面)  -- 有序,可重複
│   ├── java.util.ArrayList  (類別)   -- 動態陣列
│   ├── java.util.LinkedList (類別)   -- 雙向鏈結串列
│   └── java.util.Vector     (類別)   -- 執行緒安全的動態陣列
│
├── java.util.Set  (介面)   -- 無序,不重複
│   ├── java.util.HashSet        (類別)   -- 基於 HashMap
│   ├── java.util.LinkedHashSet  (類別)   -- 保留插入順序
│   └── java.util.TreeSet        (類別)   -- 基於紅黑樹,自然排序
│
└── java.util.Queue  (介面) -- 先進先出(FIFO)
├── java.util.PriorityQueue  (類別) -- 依優先級排序
└── java.util.Deque  (介面)  -- 雙端隊列
├── java.util.ArrayDeque (類別)
└── java.util.LinkedList (類別) -- 也同時實作了 List
二、Comparable 和 Comparator 的差異
特性:
2個介面Comparable、Comparator,用來排序物件
Module.java.base
Package.java.langInterface Comparable<T>
Module.java.base
Package.java.util Interface Comparator<T>
在 Java 中,Comparable 和 Comparator 介面都是用於對物件進行排序。
它們的主要差異如下:
三、Comparable與Comparator` 的差異比較表
補充:什麼是自然排序?
答案:數字排在大寫字母之前,大寫字母排在小寫字母之前。
四、實作一個Comparable範例
Comparable<Laptop>介面Laptop.java
package Geeks;
import java.util.Comparator;
public class Laptop implements Comparable<Laptop>{
	private String brand;
	private int ram;
	private int price;
	public String getBrand() {
		return brand;
	}
	public void setBrand(String brand) {
		this.brand = brand;
	}
 
	public int getRam() {
		return ram;
	}
	public void setRam(int ram) {
		this.ram = ram;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	@Override
	public String toString() {
	return "Laptop [brand=" + brand + ", ram=" + ram + ", price=" + price + "]";
	}
	//加上建構子,才可以在ComparableRunner.java使用new Laptop("Apple",8,1200)等
	public Laptop(String brand, int ram, int price) {
		super();
		this.brand = brand;
		this.ram = ram;
		this.price = price;
	}
	@Override
	public int compareTo(Laptop lap2) {
		//需要一個參數來做排序
		//this是"本物件"
		//this > lap2 = 正數
		//this < lap2 = 負數
		//this == lap2 0
		//使用ram這個欄位自然排序
		if(this.getRam() > lap2.getRam()) {
			return 1; //回傳正數
		}else {
			return -1;
		}
	}
}
ComparableRunner.java
package Geeks;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ComparableRunner {
	public static void main(String[] args) {
		List<Laptop> laps = new ArrayList<>();
		laps.add(new Laptop("Acer", 12, 700));
		laps.add(new Laptop("Asus", 8, 600));
		laps.add(new Laptop("Dell", 6, 900));
		laps.add(new Laptop("Apple", 8, 1200));
		
		//不知道要用哪一個排序brand or ram or price
		//Collection是泛型介面,是集合家族的共同祖先。Collection有2個很重要的子介面: Set、List
		//Collections 工具類別 - 用於List物件
		//將List傳送進Collections.sort的方法
		Collections.sort(laps);
		
		for(Laptop l: laps) {
			System.out.println(l);
		}
	}
}
五、實作一個Comparator範例
package Geeks;
import java.util.Comparator;
// 不需要實作 Comparator 介面
public class Laptop{
	private String brand;
	private int ram;
	private int price;
	
	public String getBrand() {
		return brand;
	}
	
	public void setBrand(String brand) {
		this.brand = brand;
	}
	
	public int getRam() {
		return ram;
	}
	
	public void setRam(int ram) {
		this.ram = ram;
	}
		
	public int getPrice() {
		return price;
	}
	  	
	public void setPrice(int price) {
		this.price = price;
	}
		
	@Override
	public String toString() {
	return "Laptop [brand=" + brand + ", ram=" + ram + ", price=" + price + "]";
	}
	
	
	//加上建構子
	public Laptop(String brand, int ram, int price) {
		super();
		this.brand = brand;
		this.ram = ram;
		this.price = price;
	}
}
ComparatorRunner.java
package Geeks;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ComparatorRunner {
	public static void main(String[] args) {
		List<Laptop> laps = new ArrayList<>();
		laps.add(new Laptop("MSI", 10, 1000));
		laps.add(new Laptop("Sony", 8, 600));
		laps.add(new Laptop("Lenovo", 6, 900));
		laps.add(new Laptop("Asus", 8, 1200));
		Comparator<Laptop> com = new Comparator<>() {
					
			//依品牌字母順序
			public int compare(Laptop l1, Laptop l2) {
			    return l1.getBrand().compareTo(l2.getBrand());
			}
		};
		Collections.sort(laps, com);
		for (Laptop l : laps) {
			System.out.println(l);
		}
	}
}
參考資料
Interview Question | Comparable vs Comparator in Java
https://www.youtube.com/watch?v=oAp4GYprVHM
Java Comparable vs Comparator
https://www.geeksforgeeks.org/java/comparable-vs-comparator-in-java/
版主您好,感謝您分享這篇關於 Java Comparable 與 Comparator 的技術文章!
開頭的 Collection 家族架構圖非常清晰,讓讀者能快速掌握不同集合的特性,對於理解後續的排序介面差異很有幫助。您詳細解釋了這兩個介面的主要用途,以及它們在「類別內」與「類別外」定義排序邏輯的差異,這是學習排序時很重要的觀念。
不過,在「四、實作一個Comparable範例」這部分,文章提到「Laptop類別要繼承java.util.Comparator 介面」,但後續的程式碼卻是實作 Comparable<Laptop> 介面,這兩者似乎有點出入。另外,compareTo 方法的實作內容似乎尚未完整呈現,期待能看到完整的範例程式碼,會讓讀者更容易理解實際應用。
再次感謝您的分享!也歡迎版主有空參考我的系列文「南桃AI重生記」:
https://ithelp.ithome.com.tw/users/20046160/ironman/8311